/*  -*- mode: c++; coding: utf-8; c-file-style: "stroustrup"; -*-

    Copyright 2008 Asier Aguirre <asier.aguirre@gmail.com>
    This file is part of Intromit.

    Intromit is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Intromit is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Intromit.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "python_misc.hh"
#include <stdlib.h>

// GLOBAL VARIABLES
int global_int=-123;
float global_float=3.5;
double global_double=-7.8;
derived2 global_class;
base *global_base=new derived2;

// class to delete global_base
struct global_base_deleter
{
    ~global_base_deleter() {if(global_base) delete global_base; global_base=NULL;}
};
global_base_deleter global_base_del;

// TEST FUNCTIONS
void set_global_int(int v)
{
    global_int=v;
}

/* this is a function */
int get_global_int()
{
    return global_int;
}

void set_global_float(float v)
{
    global_float=v;
}

float get_global_float()
{
    return global_float;
}

void set_global_double(double v)
{
    global_double=v;
}

double get_global_double()
{
    return global_double;
}

int func_poly()
{
    return 1;
}

int func_poly(unsigned short us)
{
    return 2;
}

int func_poly(float x)
{
    return 3;
}

int func_poly(double a, double b)
{
    return 4;
}

// function to make compiler generate types info 
void user_func(sample_enum, embed_enum,
	       embed_enum::sample_enum,
	       embed_enum::embed_struct,
	       embed_enum::embed_struct::sample_enum,
	       embed_enum::embed_struct::embed_class,
	       embed_enum::embed_struct::embed_class::sample_enum,
	       embed_enum::embed_struct::embed_class::embed_union,
	       embed_enum::embed_struct::embed_class::embed_union::sample_enum,
	       namespace_enum::sample_enum,
	       namespace_enum::namespace_nested::embed_struct)
{
    derived1 *d1=new derived1;
    base *b=d1->generalize_this();
    b->virtual_method();
    delete d1;
}

namespace_enum::namespace_nested::namespace_class::namespace_class()
{
    x=0;
}

namespace_enum::namespace_nested::namespace_class::namespace_class(int x)
{
    this->x=x;
}

int namespace_enum::namespace_nested::namespace_class::get_x()
{
    return x;
}

base::base()
{
    b=-1;
}

base::~base()
{
}

void base::set_b(int b)
{
    this->b=b;
}

int base::get_b()
{
    return b;
}

int base::virtual_method()
{
    return 99;
}

derived1::derived1()
{
    d1=-2;
}

derived1::~derived1()
{
}

void derived1::set_d1(float d1)
{
    this->d1=d1;
}

float derived1::get_d1()
{
    return d1;
}

int derived1::virtual_method()
{
    return 66;
}

base *derived1::generalize_this()
{
    return this;
}

derived2::derived2()
{
    d2=-4;
}

derived2::~derived2()
{
}

void derived2::set_d2(double d2)
{
    this->d2=d2;
}

double derived2::get_d2()
{
    return d2;
}

int derived2::virtual_method()
{
    return 33;
}

derived1 *derived2::generalize_derived1()
{
    return this;
}

base *derived2::generalize_base()
{
    return this;
}

// TEST INHERITANCE W/O CTOR AND DTOR

base_wo_ctor::~base_wo_ctor()
{
}

int base_wo_ctor::vmethod()
{
    return 1;
}

int derived_wo_ctor::vmethod()
{
    return 2;
}

base_wo_ctor &derived_wo_ctor::generalize()
{
    return *this;
}

// TEST BASE CLASS CTOR/DTOR EXECUTION

unsigned exec_global;

exec2::exec2()
{
    member2=987.654;
    exec_global=0;
}

exec2::~exec2()
{
    exec_global|=1<<2;
}

void exec2::set_member1(float value)
{
    member1=value;
}

exec4::exec4()
{
    member4=123.987;
}

exec4::~exec4()
{
    exec_global|=1<<4;
}

// TEST FUNCTIONS INSIDE NAMESPACE
int func_namespace::namespaced_func(int a, unsigned b)
{
    return -7+a+b;
}
